home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The X-Philes (2nd Revision)
/
The X-Philes Number 1 (1995).iso
/
xphiles
/
hp48_2
/
uart
< prev
next >
Wrap
Text File
|
1995-03-31
|
9KB
|
299 lines
Article 5921 of comp.sys.handhelds:
Path: en.ecn.purdue.edu!noose.ecn.purdue.edu!samsung!think.com!snorkelwacker.mit.edu!ai-lab!rice-chex!bson
From: bson@rice-chex.ai.mit.edu (Jan Brittenson)
Newsgroups: comp.sys.handhelds
Subject: The HP-48 UART - Basic Usage
Message-ID: <14901@life.ai.mit.edu>
Date: 15 Apr 91 02:24:49 GMT
Sender: news@ai.mit.edu
Organization: nil
Lines: 285
I hope the following brief and basic explanation will prove useful
to anyone interested in using the HP-48 UART for serial wire
communication from ML programs. Please e-mail me if you find any
inconsistencies in it.
This draft, is dated April 14, 1991. Do whatever you wish with it -
publication, printing, and other forms of mass distribution highly
encouraged.
-- Jan Brittenson
bson@ai.mit.edu
O /
\/
/\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
O \
INRODUCTION
-----------
The HP-48 UART (Universal Asynchronous Receiver-Transmitter) is
capable of simultaneously sending and receiving data at speeds of
1200, 2400, 4800 and 9600 bps (bits per second). This document deals
not with how to communicate from a user or system RPL program, but how
to do so from ML (Machine Language). Only the basics are covered:
o I/O registers and system data
o ML routines
o About communication
o Sample program
HP-48 UART REGISTERS
--------------------
The list below describes the registers and memory locations
relevant to the basic UART operation. Each entry consists of a header:
name.size #address/access
The name is a symbolic name. The size is the size rounded up to an
integral nybble. The address is the memory location in a default
system configuration. The access specifices whether the register or
location can read from, written into, or both.
XMIT.2 #00116/write
UART transmitter register. Writing a character to this
address causes it to be transmitted serially. Make sure the
transmitter is finished with the previous character before
writing.
RECV.2 #00114/read
UART receiver register. The most recently received
character can be found here. Must be read before the next
character has been received.
RECVBUF.256 #701FC/read-write
256-character serial receive buffer. Data is automatically
added to the buffer via interrupts into system code as they
arrive in the UART receiver.
RECVHEAD.8 #703FC/read-write
8-nybble serial buffer head. Contains size, get, and put
counters. Use the ML routine at #31289 (see below) to
obtain the next character.
USTAT.1 #00112/read
-------------
| | |RR|XR| XR: XMIT ready
------------- RR: RECV ready
3 2 1 0
XR is set if XMIT is ready to accept another character,
otherwise it is cleared. RR is set when a character is
available in the UART RECV register. Do not alter bits 3 and
2.
PACING.1 #70401/read-write
-------------
|XH| |RH|RF| XH: XMIT handshaking recognized
------------- RH: RECV handshaking used
3 2 1 0 RF: XOFF transmitted
Bits 0 and 2 must not be modified, as they are RAM shadows
for location #0011A. Handshaking on the HP-48 is implemented
in software. The RF bit signals that the RECV system interrupt
routine has sent an XOFF to XMIT.
PACRQ.1 #70402/read-write
-------------
|RF| | | | RF: XOFF transmission requested
-------------
3 2 1 0
The RF bit is set when RECVBUF is almost filled up but XMIT
is busy. This bit should be checked before a character is
transmitted.
PARITY.1 #70403/read-write
------------- PE: Parity enable, 0 = None
|PE|P2|P1|P0|
------------- P2 P1 P0
3 2 1 0 1 0 0 Even 2
1 0 1 Odd 1
1 1 0 Spc 4
1 1 1 Mark 3
P0-P2 must all be zero if no parity is used. Parity is
implemented in software on the HP-48, and is resolved before
characters are added to RECVBUF (see above). For transmission,
the ML routine at #3113D (see below) can be used to adjust
bits 0-7 of register A according to the current parity
setting.
BPS.3 #0010D/read-write
11-bit register specifying the current serial transmission
speed.
Value Speed, BPS
#600 9600
#400 4800
#200 2400
#000 1200
Bit 3 of #10E is used for other purposes, and care must be
taken not to alter it. Both receiver and transmitter operate
at the same speed.
UINTR.1 #00110/read-write
------------- RI: RECV interrupt
|RI|RE|XI|XE| RE: RECV interrupt enable
------------- XI: XMIT interrupt
3 2 1 0 XE: XMIT interrupt enable
UART interrupt register. The RE bit enables RECV
interrupts, which are triggered when a character becomes
available in the RECV register. XE enables XMIT empty
interrupts, which are triggered whenever XMIT is ready for a
new character. The RI and XI bits are set whenever a RECV and
XMIT interrupt has been triggered. They are checked by the
system interrupt handler to determine the cause of the
interrupt.
ROM COMMUNICATION ROUTINES
--------------------------
#310CA Check if UART XMIT ready for another character.
Checks bit 0 of USTAT.
Out:
Carry Clear if ready
#3113D Add parity to character according to current
parity setting. Parity of RECV characters can
be checked by saving the character, calling this
routine, and then comparing the results. They
should be equal. All 8 bits are left alone if
parity is `none.'
In:
A.B Character
Out:
A.B Character with parity bit in bit 7
#31289 Get next character from the serial buffer.
Out:
A.B Character
Carry Set if buffer is empty
#31085 Check if receive buffer is full. That is, if
there isn't room for one more character.
Out:
Carry Set if buffer is full.
COMMUNICATION
-------------
Character reception is done by an interrupt routine. Whenever a
character is ready in the UART RECV register, an interrupt is
triggered, and a call to the commmoninterrupt entry in the ROM is
made. The interrupt handler in ROM looks at the UINTR bits to find the
cause of the interrupt; if it was RI, then a dispatch to the RECV
interrupt handler is made. The RECV handler retrieves the character
and adds it to the buffer. If there are less than 16 characters
available, it attempts to transmit an XOFF, if handshaking (see the
PACING location) is enabled. If the transmitter is busy, it instead
flags an XOFF request in the PACRQ location. Thus, a program
transmitting data has to check this flag before each successive
character is transmitted; if it's set, an XOFF should be transmitted.
No XMIT interrupt handler exists in ROM, and no user handler can be
added. It is debatable whether this is useful for implementing light
sleep between transmitted characters. Or rather, how useful that would
be. I do not know whether the UART is operational in light sleep,
or whether it has the option of remaining so.
In general, it is much more desirable to deal with RECVBUF via the
ROM routines than dealing with the raw operation of the RECV I/O
register. Still, I can conceive of at least one possible instance
where dealing with the RECV register directly is desirable. That is if
the receiver can operate in light sleep, and you don't want to be
woken up from your light sleep by incoming serial data. In such a case
it may be desirable to generally keep RECV interrupts disabled and
employ polling.
There isn't any XOFF detection in the RECV interrupt handler. The
code that does the transmission has to check whether the next
character in RECVBUF is an XOFF. This seems like a flaw to me - the
`MS-DOS XON/XOFF syndrome.' It breaks when XOFF is not the first
character in RECVBUF and further transmission is required before
RECVBUF is cycled through. Instead, the RECV interrupt handler should
have checked for XOFF (if enabled) and a RAM bit used to flag a paused
condition to the transmitting code.
A SAMPLE PROGRAM
----------------
The following sample program (STAR syntax) creates a loopback.
Whatever is received in RECVBUF is echoed on XMIT. The program ignores
parity and RECV interrupt handler XOFF requests. Can you think of a
way to add these features?
getc_srecvbuf_a_p = 0x31289
uart_xmit_rdy_p = 0x310ca
xmit = 0x116
echo:
call getc_srecvbuf_a_p ; A.B = RECVBUF character
brcs echo ; RECVBUF empty - loop
move a, r0 ; R0.B = character
$100:
call uart_xmit_rdy_p ; XMIT RDY?
brcs $100 ; Nope - loop until it is
move.5 xmit, d0
move r0, c
move.b c, @d0 ; XMIT = character
jump echo ; Echo next character
[This line and the signature below are not part of the document.]
-- Jan Brittenson
bson@ai.mit.edu